package com.example.websockettest.webSocket.ProxyPost;

import com.alibaba.fastjson.JSONObject;
import com.example.websockettest.webSocket.MyTool.BodyData;
import com.example.websockettest.webSocket.MyTool.MyRole;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

/**
 * @author pengshuzhu
 * 该方法实现了将请求gpt接口通过本地clash代理给openai
 */
public class ProxyExample {
    public static void test() throws Exception {
       String gptresponse=response("你好");
    }
    public static String response(String prompt) throws IOException {
        return response(prompt,30);//默认30秒超时
    }
    public static String response(String prompt,int overTime) throws IOException {
        long straTime=System.currentTimeMillis();
        // 设置代理服务器地址和端口号
        String proxyHost = "127.0.0.1";
        int proxyPort = 7890;

        // 创建代理对象
        Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort));
        //String modle="davinci";
        /*
        * 除了davinci-codex，OpenAI还提供了许多其他预训练模型，包括：

        davinci: OpenAI最强大的模型，可以执行各种自然语言处理任务。
        curie: OpenAI推出的一种通用模型，可以完成各种NLP任务，包括文本分类、摘要生成和语言生成。
        babbage: 一个相对较小的模型，适合简单的NLP任务和探索性研究。
        ada: 专为NLP和理解任务设计的模型，具有强大的推理和推理能力。
        cushman: 专为对话系统设计的模型，适合构建对话式AI应用程序。
        davinci-instruct-beta: 用于执行程序和生成代码的模型，可以读懂英语代码注释并将其转换为Python代码。
        ，除了这些预训练模型，OpenAI还提供了一些特殊用途的API，如GPT-3的API、Codex API等。
        * */
        // 创建 URLConnection 对象，并设置代理
        // URL url = new URL("https://api.openai.com/v1/engines/"+modle+"/completions");
        //设置 API 地址和请求头信息
        URL url = new URL("https://api.openai.com/v1/chat/completions");
        URLConnection conn = url.openConnection(proxy);//通过代理发送请求
        // 设置请求头信息
        //并用utf8进行编码
        conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
        conn.setRequestProperty("Authorization", "Bearer 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");

        // 发送 POST 请求并输出响应结果
        //首先将 conn 的输入流打开
        conn.setDoOutput(true);
        OutputStreamWriter writer = null;
        try {
            writer = new OutputStreamWriter(conn.getOutputStream());
        } catch (IOException e) {
            return "chatgpt连接失败";
        }
        ArrayList<MyRole> myRoleList=new ArrayList<>();
        //将字符集编码好，统一，避免乱码
        String encodedPrompt = URLEncoder.encode(prompt, "UTF-8");
        myRoleList.add(new MyRole("user",encodedPrompt));
        //myRoleList.add(new MyRole("user",prompt));
        BodyData bodyData=new BodyData("gpt-3.5-turbo",1,50,1, myRoleList);
        //将请求信息写入输入流
        writer.write(JSONObject.toJSONString(bodyData));
        System.out.println(JSONObject.toJSONString(bodyData));
        writer.flush();
        BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(),"UTF-8"));
        String line;
        String content="空";

        while ((line = reader.readLine()) != null) {
            long nowTime=System.currentTimeMillis();
            if(nowTime-straTime>=overTime* 1000L){//超时5秒，返回请求超时
                //请求超时
                writer.close();
                reader.close();
                return "请求处理超时";
            }
            line=URLDecoder.decode(line,String.valueOf(StandardCharsets.UTF_8));
            System.out.println(line+"这是gpt返回的消息");
            JSONObject a=JSONObject.parseObject(line);
            try {
                String message=JSONObject.parseObject(a.getJSONArray("choices").get(0).toString()).getString("message");
                content=JSONObject.parseObject(message).getString("content");
                System.out.println(content);
            } catch (Exception e) {
                System.out.println(e.getMessage()+"This is error Message");
            }
        }
        writer.close();
        reader.close();
        return content;
    }

    public static String response(List<MyRole> myRoleList) throws IOException {
        // 设置代理服务器地址和端口号
        String proxyHost = "127.0.0.1";
        int proxyPort = 7890;

        // 创建代理对象
        Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort));
        //String modle="davinci";
        /*
        * 除了davinci-codex，OpenAI还提供了许多其他预训练模型，包括：

        davinci: OpenAI最强大的模型，可以执行各种自然语言处理任务。
        curie: OpenAI推出的一种通用模型，可以完成各种NLP任务，包括文本分类、摘要生成和语言生成。
        babbage: 一个相对较小的模型，适合简单的NLP任务和探索性研究。
        ada: 专为NLP和理解任务设计的模型，具有强大的推理和推理能力。
        cushman: 专为对话系统设计的模型，适合构建对话式AI应用程序。
        davinci-instruct-beta: 用于执行程序和生成代码的模型，可以读懂英语代码注释并将其转换为Python代码。
        ，除了这些预训练模型，OpenAI还提供了一些特殊用途的API，如GPT-3的API、Codex API等。
        * */
        // 创建 URLConnection 对象，并设置代理
        // URL url = new URL("https://api.openai.com/v1/engines/"+modle+"/completions");
        //设置 API 地址和请求头信息
        URL url = new URL("https://api.openai.com/v1/chat/completions");
        URLConnection conn = url.openConnection(proxy);//通过代理发送请求
        // 设置请求头信息
        //并用utf8进行编码
        conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
        conn.setRequestProperty("Authorization", "Bearer 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");

        // 发送 POST 请求并输出响应结果
        //首先将 conn 的输出流打开
        conn.setDoOutput(true);
        OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());
        //ArrayList<MyRole> myRoleList=new ArrayList<>();
        //将字符集编码好，统一，避免乱码
        //String encodedPrompt = URLEncoder.encode(prompt, "UTF-8");
        ArrayList<MyRole> newMyRole=new ArrayList<>();
        for(MyRole e:myRoleList){
            newMyRole.add(new MyRole(URLEncoder.encode(e.getRole(),"UTF-8"),URLEncoder.encode(e.getContent(), "UTF-8")));
        }

        //myRoleList.add(new MyRole("user",encodedPrompt));
        BodyData bodyData=new BodyData("gpt-3.5-turbo",1,2000,1, (ArrayList<MyRole>) myRoleList);
        //将请求信息写入输出流
        writer.write(JSONObject.toJSONString(bodyData));
        System.out.println(JSONObject.toJSONString(bodyData));
        writer.flush();
        BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(),"UTF-8"));
        String line;
        String content="空";
        while ((line = reader.readLine()) != null) {
            //line=URLDecoder.decode(line,String.valueOf(StandardCharsets.UTF_8));
            System.out.println(line+"这是gpt返回的消息");
            JSONObject a=JSONObject.parseObject(line);
            try {
                String message=JSONObject.parseObject(a.getJSONArray("choices").get(0).toString()).getString("message");
                content=JSONObject.parseObject(message).getString("content");
                System.out.println(content);
            } catch (Exception e) {
                System.out.println(e.getMessage()+"This is error Message");
            }
        }
        writer.close();
        reader.close();
        return content;
    }
}
